#include "stdafx.h"
#include "RealTimeDataSet.h"
#include "gtest\gtest.h"
#include "base\at_exit.h"
#include "base\message_loop.h"
#include "base\location.h"
#include "base\bind.h"
#include <vld.h>

namespace
{
	const static  int kUpdateDataCount = 1024*4;
	struct ArrayContainer
	{
	public:
		typedef  boost::shared_array<uint16>	IntArray;
		void  Push(IntArray  array)		{	array_list.push_back(array);	}

		uint16  GetAt(int  index)	
		{
			return array_list[index/kUpdateDataCount][index%kUpdateDataCount];
		}
	private:
		std::vector<IntArray>	array_list;
	};
}

class  RealTimeDataSetTest: public testing::Test
{
public:
	virtual void SetUp()
	{
		data_send_count = 0;
		data_kept_count = 0;
		data_observer = NULL;
		data_set =  new DataManager::RealTimeDataSet ;
	}

	void  BeginCollectData( DataAcquisition::IChannelDataObserver *  observer)
	{
		data_observer = observer;
		message_loop.PostDelayedTask(FROM_HERE, base::Bind(&RealTimeDataSetTest::UpdateData, base::Unretained(this)),
			base::TimeDelta::FromMilliseconds(20)); 
	}

	void  UpdateData()
	{
		using  boost::shared_array;
		
		const static  int kStatisticDataCount = kUpdateDataCount/ (DataManager::kStatisticsGranularity);

		shared_array<uint16>	raw_data(new uint16[kUpdateDataCount]);
		for(int i=0;i<kUpdateDataCount; ++i)
		{
			raw_data[i] = rand();
		}
		raw_data_container.Push(raw_data);
		data_observer->OnRawDataUpdate(raw_data, kUpdateDataCount);

		shared_array<uint16>	min_data(new uint16[kStatisticDataCount]);
		data_observer->OnMinDataUpdate(min_data, kStatisticDataCount);

		shared_array<uint16>	max_data(new uint16[kStatisticDataCount]);
		data_observer->OnMaxDataUpdate(max_data, kStatisticDataCount);

		shared_array<uint16>	average_data(new uint16[kStatisticDataCount]);
		data_observer->OnAverageDataUpdate(average_data, kStatisticDataCount );

		data_send_count += kUpdateDataCount;
		if( data_kept_count>= 2 * DataManager::DataFrame::kDataFrameIndexCount)
			data_kept_count = DataManager::DataFrame::kDataFrameIndexCount ;
		data_kept_count += kUpdateDataCount;
		
		scoped_ptr<DataManager::IRealTimeDataReader>  reader( data_set->GetDataReader()   );
// 		EXPECT_EQ( reader->GetEndIndex(), data_send_count);
// 		EXPECT_EQ( reader->GetBeginIndex(), data_send_count-data_kept_count);
		for(int64 index = reader->GetBeginIndex(); index<reader->GetEndIndex(); ++index )
		{
			uint16   value;
			reader->GetAt(index, (UCHAR*)&value);
			EXPECT_EQ(value, raw_data_container.GetAt(index));
		}
		reader->Stop();
// 		EXPECT_EQ( reader->GetEndIndex(), data_send_count);
// 		EXPECT_EQ( reader->GetBeginIndex(), data_send_count-data_kept_count);
		for(int64 index = reader->GetBeginIndex(); index<reader->GetEndIndex(); ++index )
		{
			uint16   value;
			reader->GetAt(index, (UCHAR*)&value);
			EXPECT_EQ(value, raw_data_container.GetAt(index));
		}
		reader->Run();
		if(data_send_count >=  kDataCount)
			message_loop.Quit();
		else
			message_loop.PostDelayedTask(FROM_HERE, base::Bind(&RealTimeDataSetTest::UpdateData, base::Unretained(this)),
				base::TimeDelta::FromMilliseconds(20)); 
	}
 
protected:
	base::AtExitManager	at_exit;
	
	MessageLoopForIO			message_loop;
	DataAcquisition::IChannelDataObserver *	data_observer;
	scoped_refptr<DataManager::RealTimeDataSet> 	data_set;
	int					data_send_count;
	int					data_kept_count;
	
	ArrayContainer		raw_data_container;
	const	static int  kDataCount =  0x1<<14 <<2;
};

TEST_F(RealTimeDataSetTest, Test)
{
	BeginCollectData( data_set.get());
	message_loop.Run();
	std::cout<<"End"<<std::endl;
}